﻿#ifndef SINGLETEMPLATE_H
#define SINGLETEMPLATE_H
#include <iostream>
#include <memory>
#include <mutex>
template <typename T>
class Single_T
{
private:
    Single_T() = delete;
    Single_T(const Single_T &other) = delete;
    Single_T &operator=(const Single_T<T> &st) = delete;
    ~Single_T()
    {
        std::cout << "this is auto safe template destruct" << std::endl;
    }
public:
    static std::shared_ptr<T> GetInst()
    {
        if(single != nullptr)//双if判断解决性能问题
        {
            return single;
        }
        std::lock_guard<std::mutex> lockGuard(s_mutex);
        if(single != nullptr)
        {
            s_mutex.unlock();
            return single;
        }
        single = std::shared_ptr<T>(new T,std::default_delete<T>());
        return single;
    }

private:
    static std::shared_ptr<T> single;
    static std::mutex s_mutex;
};
template <typename T>
std::shared_ptr<T> Single_T<T>::single = nullptr;

template <typename T>
std::mutex Single_T<T>::s_mutex;

#define SINGLETON(Class)                            \
private:                                            \
    Class();                                        \
    ~Class();                                       \
    Class(const Class &other) = delete;             \
    Class& operator=(const Class &other) = delete;  \
    friend class Single_T<Class>;                   \
    friend struct std::default_delete<Class>;       \
public:                                             \
    static std::shared_ptr<Class> GetInst()         \
    {                                               \
        return Single_T<Class>::GetInst();          \
    }

#endif // SINGLETEMPLATE_H
